﻿using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Net.Sockets;
using System.Net;
using System.Data;

namespace SocketLibrary
{
    public class TcpSvrManager
    {
        /// <summary>
        /// 连接对象结合
        /// </summary>
        List<TcpSvr> m_socket_list = new List<TcpSvr>();

        /// <summary>
        /// 接受到命令消息是触发事件
        /// </summary>
        public event CommandReceivedEventHandler CommandReceived;

        /// <summary>
        /// 后台侦听线程
        /// </summary>
        private BackgroundWorker m_bw_listener;

        /// <summary>
        /// 侦听的通讯
        /// </summary>
        private Socket m_listener_socket;

        /// <summary>
        /// 侦听端口
        /// </summary>
        private int m_listen_port = 8000;

        /// <summary>
        /// 侦听端口
        /// </summary>
        public int ListenPort
        {
            get { return m_listen_port; }
            set { m_listen_port = value; }
        }

        private string m_db_con_string;

        /// <summary>
        /// 数据库访问字符串
        /// </summary>
        public string DBConString
        {
            get { return m_db_con_string; }
            set { m_db_con_string = value; }
        }
	

        public TcpSvrManager(int i_port,string i_db_con_string)
        {
            m_listen_port = i_port;

            m_db_con_string = i_db_con_string;

            DbHelperOra.m_con_string = i_db_con_string;

            StartService();
        }

        /// <summary>
        /// 开始服务
        /// </summary>
        public void StartService()
        {
            m_bw_listener = new BackgroundWorker();

            m_bw_listener.WorkerSupportsCancellation = true;
            m_bw_listener.DoWork += new DoWorkEventHandler(StartToListen);
            m_bw_listener.RunWorkerAsync();
        }

        /// <summary>
        /// 开始侦听端口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void StartToListen(object sender, DoWorkEventArgs e)
        {
            this.m_listener_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            this.m_listener_socket.Bind(new IPEndPoint(IPAddress.Any, this.m_listen_port));
            this.m_listener_socket.Listen(200);
            while (true)
                this.CreateSocketObj(this.m_listener_socket.Accept());
        }

        /// <summary>
        /// 对一个连接对象收发数据
        /// </summary>
        /// <param name="i_socket"></param>
        private void CreateSocketObj(Socket i_socket)
        {
            TcpSvr t_socket_obj = new TcpSvr(i_socket);
            t_socket_obj.CommandReceived += new CommandReceivedEventHandler(CommandReceivedData);
            t_socket_obj.Disconnected += new ServerDisconnectedEventHandler(SocketDisconnected);
           
            this.m_socket_list.Add(t_socket_obj);
           
        }

        /// <summary>
        /// 回送数据到客户端
        /// </summary>
        /// <param name="i_command"></param>
        public void SendCommand(CommandInfo i_command)
        {
            TcpSvr t_socket = null;

            foreach (TcpSvr t_st in m_socket_list)
            {
                if (t_st.ConnectedIP == i_command.SenderIP)
                {
                    t_socket = t_st;
                    break;
                }
            }

            t_socket.SendCommand(i_command);
        }

        /// <summary>
        /// 接受到数据，处理之后回送
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CommandReceivedData(object sender, CommandEventArgs e)
        {
            if (CommandReceived != null)
                CommandReceived(this, e);

            CommandInfo t_cmd = GetCommand(e.CmdInfo);
           
            SendCommand(t_cmd);
        }

        private CommandInfo GetCommand(CommandInfo i_cmd)
        {
            CommandInfo t_cmd = new CommandInfo();
            if (i_cmd.CommandType == CommandType.ExcuteSQL)
            {
                try
                {
                    int t_ret = DbHelperOra.ExecuteSql(i_cmd.ToString());
                    t_cmd.SenderIP = i_cmd.SenderIP;
                    t_cmd.DataSign = i_cmd.DataSign;
                    t_cmd.CommandType = i_cmd.CommandType;
                    t_cmd.SetSendData(t_ret);
                }
                catch (Exception ex)
                {
                    t_cmd.SenderIP = i_cmd.SenderIP;
                    t_cmd.DataSign = i_cmd.DataSign;
                    t_cmd.CommandType = i_cmd.CommandType;
                    t_cmd.ExData = ex.Message;
                    t_cmd.SetSendData(-1);
                }
            }
            else if (i_cmd.CommandType == CommandType.QueryData)
            {
                try
                {
                    DataSet t_ds = DbHelperOra.Query(i_cmd.ToString());
                    t_cmd.SenderIP = i_cmd.SenderIP;
                    t_cmd.DataSign = i_cmd.DataSign;
                    t_cmd.CommandType = i_cmd.CommandType;
                    t_cmd.SetSendData(t_ds);
                }
                catch (Exception ex)
                {
                    t_cmd.SenderIP = i_cmd.SenderIP;
                    t_cmd.DataSign = i_cmd.DataSign;
                    t_cmd.CommandType = i_cmd.CommandType;
                    t_cmd.ExData = ex.Message;
                }
            }

            return t_cmd;
        }

        /// <summary>
        /// 关闭连接之后移除这个连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SocketDisconnected(object sender, SocketEventArgs e)
        {
            RemoveSocket(e.IP);
                
        }

        /// <summary>
        /// 移除连接
        /// </summary>
        /// <param name="i_ip"></param>
        /// <returns></returns>
        private bool RemoveSocket(IPAddress i_ip)
        {
            lock (this)
            {
                int index = this.IndexOfSocket(i_ip);
                if (index != -1)
                {
                    
                    this.m_socket_list.RemoveAt(index);
          
                    return true;
                }
                return false;
            }
        }

        /// <summary>
        /// 找到连接
        /// </summary>
        /// <param name="i_ip"></param>
        /// <returns></returns>
        private int IndexOfSocket(IPAddress i_ip)
        {
            int index = -1;
            foreach (TcpSvr t_socket in this.m_socket_list)
            {
                index++;
                if (t_socket.ConnectedIP.Equals(i_ip))
                    return index;
            }
            return -1;
        }

	
    }
}
